package org.jsola.hr.service.impl;

import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsola.admin.service.ISiteService;
import org.jsola.admin.vo.SiteVO;
import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.ICompanyContractQuotaRecordDAO;
import org.jsola.hr.dto.CompanyContractQuotaRecordAddDTO;
import org.jsola.hr.dto.CompanyContractQuotaRecordUpdateDTO;
import org.jsola.hr.entity.CompanyContractQuotaRecordDO;
import org.jsola.hr.entity.CompanyDO;
import org.jsola.hr.query.CompanyContractQuotaRecordQuery;
import org.jsola.hr.service.ICompanyContractQuotaRecordService;
import org.jsola.hr.service.ICompanyService;
import org.jsola.hr.vo.CompanyContractQuotaRecordVO;
import org.jsola.hr.vo.ContractRechargeVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 员工自定义信息关联变量
 *
 * @author zhr
 */
@Slf4j
@Service("hrCompanyContractQuotaRecordServiceImpl")
public class CompanyContractQuotaRecordServiceImpl implements ICompanyContractQuotaRecordService {

    @Autowired
    private ICompanyContractQuotaRecordDAO companyContractQuotaRecordDAO;

    @Autowired
    private ICompanyService companyService;

    @Lazy
    @Autowired
    private ISiteService siteService;


    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public CompanyContractQuotaRecordVO save(CompanyContractQuotaRecordAddDTO companyContractQuotaRecordAddDTO, TokenUser tokenUser) {
        // 转DO
        CompanyContractQuotaRecordDO companyContractQuotaRecordDO = companyContractQuotaRecordAddDTO.to(CompanyContractQuotaRecordDO.class);
        // 保存
        companyContractQuotaRecordDO = save(companyContractQuotaRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return companyContractQuotaRecordDO.to(CompanyContractQuotaRecordVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(CompanyContractQuotaRecordUpdateDTO companyContractQuotaRecordUpdateDTO, TokenUser tokenUser) {
        //转DO
        CompanyContractQuotaRecordDO companyContractQuotaRecordDO = companyContractQuotaRecordUpdateDTO.to(CompanyContractQuotaRecordDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(companyContractQuotaRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... companyContractQuotaRecordIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) companyContractQuotaRecordIds);
    }


    @Override
    public CompanyContractQuotaRecordVO selectById(String companyContractQuotaRecordId, String siteId) {
        CompanyContractQuotaRecordDO companyContractQuotaRecordDO = selectDOById(companyContractQuotaRecordId, siteId);
        if (companyContractQuotaRecordDO == null) {
            return null;
        }
        return companyContractQuotaRecordDO.to(CompanyContractQuotaRecordVO.class);
    }


    @Override
    public List<CompanyContractQuotaRecordVO> select(CompanyContractQuotaRecordQuery companyContractQuotaRecordQuery, String siteId) {
        List<CompanyContractQuotaRecordDO> companyContractQuotaRecordDOList = selectDO(companyContractQuotaRecordQuery, siteId);
        if (CollectionUtils.isEmpty(companyContractQuotaRecordDOList)) {
            return companyContractQuotaRecordDOList == null ? null : new ArrayList<>();
        }
        return companyContractQuotaRecordDOList.stream()
                .map(companyContractQuotaRecordDO -> companyContractQuotaRecordDO.to(CompanyContractQuotaRecordVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(CompanyContractQuotaRecordQuery companyContractQuotaRecordQuery, String siteId) {
        Example example = buildExample(companyContractQuotaRecordQuery, siteId);
        return companyContractQuotaRecordDAO.selectCountByExample(example);
    }

    @Override
    public Page<CompanyContractQuotaRecordVO> selectPage(CompanyContractQuotaRecordQuery companyContractQuotaRecordQuery, String siteId) {
        Example example = buildExample(companyContractQuotaRecordQuery, siteId);
        Page<CompanyContractQuotaRecordDO> page = companyContractQuotaRecordDAO.selectPageByExample(example,
                companyContractQuotaRecordQuery.getPageNo(),
                companyContractQuotaRecordQuery.getPageSize());

        return page.to(CompanyContractQuotaRecordVO.class);
    }

    @Override
    public CompanyContractQuotaRecordDO selectDOById(String companyContractQuotaRecordId, String siteId) {
        return listById(companyContractQuotaRecordId, siteId);
    }

    @Override
    public List<CompanyContractQuotaRecordDO> selectDO(CompanyContractQuotaRecordQuery companyContractQuotaRecordQuery, String siteId) {
        Example example = buildExample(companyContractQuotaRecordQuery, siteId);
        return companyContractQuotaRecordDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example
     *
     * @param companyContractQuotaRecordQuery 查询参数
     * @param siteId                          所属站点id
     * @return example
     */
    private Example buildExample(CompanyContractQuotaRecordQuery companyContractQuotaRecordQuery, String siteId) {
        Example example = new Example(CompanyContractQuotaRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (StringUtils.isNotBlank(companyContractQuotaRecordQuery.getQuotaId())) {
            example.and().andEqualTo("quotaId", companyContractQuotaRecordQuery.getQuotaId());
        }
        if (StringUtils.isNotBlank(companyContractQuotaRecordQuery.getCompanyId())) {
            example.and().andEqualTo("companyId", companyContractQuotaRecordQuery.getCompanyId());
        }
        // 排序
        ExampleKit.setExampleOrder(example, companyContractQuotaRecordQuery.getOrders());
        return example;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public CompanyContractQuotaRecordVO saveOrUpdate(CompanyContractQuotaRecordUpdateDTO companyContractQuotaRecordUpdateDTO, TokenUser tokenUser) {
        CompanyContractQuotaRecordDO companyContractQuotaRecordDO = companyContractQuotaRecordUpdateDTO.to(CompanyContractQuotaRecordDO.class);
        CompanyContractQuotaRecordDO companyContractQuotaRecordDOTmp = selectDOBySiteId(tokenUser.getSiteId());

        if (StringUtils.isBlank(companyContractQuotaRecordUpdateDTO.getId())) {
            //添加判断是否存在
            if (Objects.nonNull(companyContractQuotaRecordDOTmp)) {
                return companyContractQuotaRecordDOTmp.to(CompanyContractQuotaRecordVO.class);
            }
            // 保存
            companyContractQuotaRecordDO = save(companyContractQuotaRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
            return companyContractQuotaRecordDO.to(CompanyContractQuotaRecordVO.class);
        } else {
            //编辑判断是否存在
            if (Objects.isNull(companyContractQuotaRecordDOTmp)) {
                return null;
            }
            //根据主键更新，只更新非null值
            updateByIdSelective(companyContractQuotaRecordDO, tokenUser.getSiteId(), tokenUser.getUserId());
            return companyContractQuotaRecordDO.to(CompanyContractQuotaRecordVO.class);
        }
    }

    @Override
    public CompanyContractQuotaRecordDO selectDOBySiteId(String siteId) {
        Example example = new Example(CompanyContractQuotaRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        return companyContractQuotaRecordDAO.selectOneByExample(example);
    }

    @Override
    public CompanyContractQuotaRecordVO getBySite(String siteId) {
        Example example = new Example(CompanyContractQuotaRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId)
                .andEqualTo("quotaId", "system");
        return companyContractQuotaRecordDAO.selectOneByExample(example).to(CompanyContractQuotaRecordVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public CompanyContractQuotaRecordVO addRecord(ContractRechargeVO vo, TokenUser tokenUser) {
        Example example = new Example(CompanyContractQuotaRecordDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", vo.getCompanyId());
        example.orderBy("gmtCreate").desc();
        List<CompanyContractQuotaRecordDO> dos = companyContractQuotaRecordDAO.selectByExample(example);
        CompanyContractQuotaRecordDO before = new CompanyContractQuotaRecordDO();
        if (!CollectionUtils.isEmpty(dos)) {
            before = dos.get(0);
        }
        CompanyContractQuotaRecordDO aDo = new CompanyContractQuotaRecordDO();
        aDo.setQuotaId(before.getQuotaId());
        aDo.setCompanyId(vo.getCompanyId());
        if ("system".equals(aDo.getCompanyId())) {
            SiteVO siteVO = siteService.selectById(tokenUser.getSiteId(), tokenUser.getSiteId());
            aDo.setCompanyName(siteVO.getName());
        } else {
            CompanyDO companyDO = companyService.selectDOById(vo.getCompanyId(), tokenUser.getSiteId());
            aDo.setCompanyName(companyDO.getName());
        }
        aDo.setType(vo.getType());
        aDo.setContractCount(Convert.toInt(vo.getContractCount(), 0));
        aDo.setBeforeContractCount(Convert.toInt(before.getContractCount(), 0));
        aDo.setAfterContractCount(Convert.toInt(before.getContractCount(), 0) + vo.getContractCount());
        aDo.setFaceCount(Convert.toInt(vo.getFaceCount(), 0));
        aDo.setBeforeFaceCount(Convert.toInt(before.getFaceCount(), 0));
        aDo.setAfterFaceCount(Convert.toInt(before.getFaceCount(), 0) + vo.getFaceCount());
        return save(aDo, tokenUser.getSiteId(), tokenUser.getUserId()).to(CompanyContractQuotaRecordVO.class);
    }

}




